package com.mes.common.util;

import java.util.LinkedList;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.criterion.Projections;
import org.hibernate.impl.AbstractQueryImpl;

import com.mes.common.dao.IExecuteQueryDao;
import com.mes.common.exception.bo.BaseBusinessException;
import com.mes.common.property.ObjectConstants;
import com.mes.common.sf.JsonUtil;
import com.mes.common.spring.SpringUtils;

/**
 * 用于为一组数据附加分页信息的包装类.
 * 
 */
public class Page {
	public final static int DEFAULT_PAGE_SIZE = 100;
	private static final Log log = LogFactory.getLog(Page.class);
	private static  IExecuteQueryDao  executeQueryDao ;
	private List rows;

	private Integer totalCount=0;
	/*
	 * 页面顺序，第几页，默认为第1页
	 */
	private Integer pageIndex;
	/*
	 * 页面所含记录集最大条数，默认为1000
	 */
	private Integer pageSize;
	/*
	 * 记录集总页数，共几页
	 */
	private Integer start;
	
	private Integer pageCount=0;
	private Integer firstRowSeq;

	public Integer getFirstRowSeq() {
		return firstRowSeq;
	}

	public void setFirstRowSeq(Integer firstRowSeq) {
		this.firstRowSeq = firstRowSeq;
	}
	
	public Integer getStart() {
		return start;
	}

	public void setStart(Integer start) {
		this.start = start;
	}

	public Page(Integer pageIndex, Integer pageSize) {
		super();
		this.pageIndex = pageIndex == null ? 1 : pageIndex;
		this.pageSize = pageSize == null ? DEFAULT_PAGE_SIZE : pageSize;
	}

	public void pagePro(final Query query) {
		if ( this.pageSize != null&&this.pageSize >= 0) {
			/*
			if(this.pageIndex==1){//只有=1时才需要计算总页数
			但dorado5客服表示无法实现这个功能
			未来需要这方面改善一下
			 */

			try {
				if(executeQueryDao==null)executeQueryDao= (IExecuteQueryDao) SpringUtils.getBean("executeQueryDAO");
				this.totalCount = executeQueryDao.getObjectCount((AbstractQueryImpl)query);

				if (this.totalCount % this.pageSize != 0) {
					this.pageCount = this.totalCount / this.pageSize + 1;
				} else {
					this.pageCount = this.totalCount / this.pageSize;
				}
				int f = 0;
				if(this.start == null){
					int pageIndex=(this.pageIndex==null || this.pageIndex<=0)?1:this.pageIndex;
					
					
					f = this.getpageSize() * (pageIndex - 1);
				}else {
					f = start;
				}
				query.setFirstResult(f);
				query.setMaxResults(this.getpageSize());
				this.firstRowSeq=f+1;
			} catch (BaseBusinessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} else
			log.warn("分页信息不完整！");
	}

	public void pagePro(Criteria crit) {
		if ( this.pageSize != null&&this.pageSize >= 0) {
			/*
			if(this.pageIndex==1){//只有=1时才需要计算总页数
			但dorado5客服表示无法实现这个功能
			未来需要这方面改善一下
			 */
			try {
				crit.setProjection(Projections.rowCount());
				this.totalCount = ((Integer) crit.uniqueResult());

				if (this.totalCount % this.pageSize != 0) {
					this.pageCount = this.totalCount / this.pageSize + 1;
				} else {
					this.pageCount = this.totalCount / this.pageSize;
				}

				//			}
				
				int f = 0;
				if(this.start == null){
					int pageIndex=(this.pageIndex==null || this.pageIndex<=0)?1:this.pageIndex;
					f = this.getpageSize() * (pageIndex - 1);
				}else {
					f = start;
				}
				crit.setFirstResult(f);
				crit.setMaxResults(this.getpageSize());
				this.firstRowSeq=f+1;
			} catch (HibernateException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
				crit.setProjection(null);//取消投影
				crit.setResultTransformer(Criteria.ROOT_ENTITY);//一定要设置其返回根实体啊，否则会乱
			}
		} else
			log.warn("分页信息不完整！");
	}

	/**
	 * 构造器
	 */
	public Page() {
	}

	/**
	 * 构造器
	 * 
	 * @param rows
	 *            被包装的数据
	 */
	public Page(List rows) {
		this.rows = rows;
	}

	/**
	 * 返回被包装的数据
	 * 
	 * @return
	 */
	public List getRows() {
		return rows;
	}

	/**
	 * 返回整个结果集的总记录数
	 * 
	 * @return
	 */
	public Integer getTotalCount() {
		return totalCount;
	}

	/**
	 * 设置被包装的数据
	 * 
	 * @param rows
	 *            被包装的数据
	 */
	public void setRows(List rows) {
		this.rows = rows;
	}

	/**
	 * 设置整个结果集的总记录数
	 * 
	 * @param totalCount
	 */
	public void setTotalCount(Integer totalCount) {
		this.totalCount = totalCount;
	}

	public Integer getPageIndex() {
		return pageIndex;
	}

	public void setPageIndex(Integer pageIndex) {
		this.pageIndex = pageIndex;
	}

	public Integer getpageSize() {
		return pageSize;
	}

	public void setpageSize(Integer pageSize) {
		this.pageSize = pageSize;
	}

	public Integer getPageCount() {
		return pageCount;
	}

	public void setPageCount(Integer pageCount) {
		this.pageCount = pageCount;
	}
	
	
	/**
	 * 从一个list中获取指定分页
	 * @param list
	 * @param from
	 * @param size
	 * @return
	 * @throws BaseBusinessException
	 */
	public static Page getNewPage(List list, Long from, Long size) throws BaseBusinessException
	{
		Integer rowCount = 0;

try {
	rowCount = new Integer(list.size());
	List pageList = new LinkedList();
	long to = Math.min(from + size, rowCount);
	for (int i = from.intValue(); i < to; i++) {
		pageList.add(list.get(i));
	}

	if (rowCount == null) {
		rowCount = 0;
	}

	int pageCount = 1;
	if (size == 0) {
		size = new Long(ObjectConstants.DEFAULT_PAGE_SIZE);
	}
	if (rowCount % size != 0) {
		pageCount = rowCount.intValue() / size.intValue() + 1;
	} else {
		pageCount = rowCount.intValue() / size.intValue();
	}
	Page page = new Page();
	page.setRows(pageList);
	page.setTotalCount(rowCount);
	return page;
} catch (Exception e) {
	e.printStackTrace();
	throw new BaseBusinessException(e.getMessage());
}
}

	@Override
	public String toString() {
		String result = JsonUtil.list2json(rows);
		return "{totalCount:" + totalCount + ",result:" + result + "}";
	}
}
